package com.hducms.cms.action.front;


import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.json.JSONException;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;






import com.facepp.error.FaceppParseException;
import com.facepp.http.HttpRequests;
import com.facepp.http.PostParameters;
import com.hducms.cms.Constants;
import com.hducms.cms.entity.front.FaceInfoM;
import com.hducms.cms.entity.front.UserM;
import com.hducms.cms.entity.front.UserMEntity;
import com.hducms.cms.entity.main.CmsUser;
import com.hducms.cms.entity.main.CmsUserExt;
import com.hducms.cms.service.CmsUserExtService;
import com.hducms.cms.service.CmsUserService;
import com.hducms.cms.web.CmsUtils;
import com.hducms.common.security.BadCredentialsException;
import com.hducms.common.security.UsernameNotFoundException;
import com.hducms.common.util.Base64;
import com.hducms.common.util.ClientUtils;
import com.hducms.common.util.FaceAddAdd;
import com.hducms.common.util.RSAUtils;
import com.hducms.common.web.CookieUtils;
import com.hducms.common.web.RequestUtils;
import com.hducms.common.web.ResponseUtils;
import com.hducms.common.web.session.SessionProvider;
import com.hducms.core.entity.Authentication;
import com.hducms.core.service.AuthenticationService;
import com.hducms.core.service.ConfigService;
import com.hducms.core.service.UnifiedUserService;
import com.hducms.core.web.WebErrors;
import com.octo.captcha.service.image.ImageCaptchaService;

@Controller
public class ClientLoginAct {

//	private static final Logger log = LoggerFactory.getLogger(CmsLogAct.class);
	public static final String COOKIE_ERROR_REMAINING = "_error_remaining";
	@SuppressWarnings("unused")
	@RequestMapping(value = "/clientlogin.m", method = RequestMethod.POST)
	public void submit(String username, String password, String captcha, String message,
			HttpServletRequest request, HttpServletResponse response,
			ModelMap model,String publickey) {
		Integer errorRemaining = unifiedUserMng.errorRemaining(username);
		try {
			password = RSAUtils.decryptByPrivateKey(password, Constants.privatekey);
		} catch (Exception e1) {
			System.out.println("解密失败");
			e1.printStackTrace();
		}
		//验证登陆表单
		WebErrors errors = validateSubmit(username, password,
				errorRemaining, request, response);
		
		//如果表单验证没有错误
		if (!errors.hasErrors()) {
			try {
				String ip = RequestUtils.getIpAddr(request);
				
				//认证身份，并且保存认证信息
				Authentication auth = authMng.login(username, password, ip,
						request, response, session);
				
				// 登录次数的更新！！！！！未完成数据更新~！似乎已经更新！！！！！
				cmsUserMng.updateLoginInfo(auth.getUserid(), ip);
				CmsUser user = cmsUserMng.findById(auth.getUserid());
				
				if (user.getIsDisabled()) {
					// 如果已经禁用，则退出登录。
					authMng.deleteById(auth.getAuthenticationId());
					session.logout(request, response);
					UserMEntity usermEntity = new UserMEntity();
					usermEntity.setStatus(UserMEntity.DISABLE);
					ClientUtils.resultResponse(response,usermEntity,publickey);
					return;
				}
				removeCookieErrorRemaining(request, response);
				if(user!=null){
					//登录成功,返回客户端user和状态信息
					UserMEntity usermEntity = new UserMEntity();
					CmsUserExt userE = cmsUserExtMng.findById(user.getUserId());
					UserM userM = new UserM();
					userM.setId(user.getUserId());
					userM.setUname(user.getUsername());
					if (userE != null) {
						userM.setRname(userE.getRealname());
					}
					if (userE.getUserFace() != null) {
						userM.setIdentifier(userE.getUserFace());
						userM.setFaceCount(userE.getUserFaceCount());
					}
					userM.setPatternLock(user.getPatternLock());
					userM.setClientId(user.getClientId());
					usermEntity.setStatus(UserMEntity.SUCCESS);
					usermEntity.setUserM(userM);
					ClientUtils.resultResponse(response,usermEntity,publickey);
					return;
				}else{
					//用户不存在
					UserMEntity usermEntity = new UserMEntity();
					usermEntity.setStatus(UserMEntity.ERROR);
					ClientUtils.resultResponse(response,usermEntity,publickey);
					return;
				}
			} catch (UsernameNotFoundException e) {
			    //用户不存在
				UserMEntity usermEntity = new UserMEntity();
				usermEntity.setStatus(UserMEntity.ERROR);
				ClientUtils.resultResponse(response,usermEntity,publickey);
				return;
			} catch (BadCredentialsException e) {
				//认证出错
				UserMEntity usermEntity = new UserMEntity();
				usermEntity.setStatus(UserMEntity.ERROR);
				ClientUtils.resultResponse(response,usermEntity,publickey);
				return;
			}
		}
		return ;
	}
	
	/**
	 * 用户脸不存在则创建之
	 * @author simony
	 * @param 
	 */
	@RequestMapping(value="/userfacecreat.m", method = RequestMethod.POST)
	public void userFaceCreat(HttpServletRequest request,
			@RequestParam(value="file",required=false) MultipartFile file,
			HttpServletResponse response,String publickey) {
		HttpRequests httpRequests = faceAddAdd.getTool(); //face++ 工具
		CmsUser user = CmsUtils.getUser(request); // 获取用户
		byte[] img = null; //用于接收图片二进制值
		String userName = user.getUsername();
		CmsUserExt userE = new CmsUserExt();
		userE = cmsUserExtMng.findById(user.getUserId());
		String faceId = null;
		JSONObject detectout = null;
		FaceInfoM faceInfo = new FaceInfoM();
		String personId = null; 
		if (file !=null) {
			try {
				img = file.getBytes();
			} catch (IOException e) {
				e.printStackTrace();
				faceInfo.setStatus(FaceInfoM.FACEADDERROR);
				ClientUtils.resultResponse(response,faceInfo,publickey);
				return;
			}
		}
		else {
			faceInfo.setStatus(FaceInfoM.FACEADDERROR);
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return; //如果未上传图片则返回
		}
		try {
			 detectout =  httpRequests.detectionDetect(new PostParameters().setImg(img));
		} catch (FaceppParseException e1) {
			System.out.println(e1.getErrorCode());
			faceInfo.setStatus(FaceInfoM.FACEADDERROR);
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		
		
		try {
			faceId = detectout.getJSONArray("face").getJSONObject(0).getString("face_id");
		} catch (JSONException e2) {
			e2.printStackTrace();
			faceInfo.setStatus(FaceInfoM.FACEADDERROR);
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		
		
		if (faceId == null) {
			//如果上传图片无人脸返回
			faceInfo.setStatus(FaceInfoM.FACEADDERROR);
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		//如果该用户没有人脸信息则创建person，并把此次用户提交的人脸加入到person中
		if (userE.getUserFace() == null || userE.getUserFace().equals("")) { 
			try { //创建person
				JSONObject person = httpRequests.personCreate(new PostParameters().setPersonName(userName));
				try {
					personId = person.get("person_id").toString();
				} catch (JSONException e) {
					e.printStackTrace();
				}
				System.out.println(personId);
				faceInfo.setPersonId(personId);
				cmsUserExtMng.updateFaceById(personId,user.getUserId(),userE.getUserFaceCount());
			} catch (FaceppParseException e) {
				faceInfo.setStatus(FaceInfoM.FACEADDERROR);
				ClientUtils.resultResponse(response,faceInfo,publickey);
				return;
			}
		}
		else{
			personId = userE.getUserFace();
			faceInfo.setPersonId(personId);
		}
		//把face加入到person中
		try {
			httpRequests.personAddFace(new PostParameters().setPersonName(userName).setFaceId(faceId.toString()));
			faceInfo.setFaceCount(userE.getUserFaceCount()+1);
			cmsUserExtMng.updateFaceById(personId,user.getUserId(),userE.getUserFaceCount()+1);
		} catch (FaceppParseException e) {
			e.printStackTrace(); //向person中添加人脸失败
			faceInfo.setStatus(FaceInfoM.FACEADDERROR);
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		//此次添加人脸完成后进行训练
		try {
			httpRequests.trainVerify(new PostParameters().setPersonName(userName));
		} catch (FaceppParseException e) {
			e.printStackTrace(); //训练失败
			faceInfo.setStatus(FaceInfoM.FACEADDERROR);
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		faceInfo.setStatus(FaceInfoM.FACEADDSUCCESS);
		ClientUtils.resultResponse(response,faceInfo,publickey);
		return;
	}
	/**
	 * 客户端人脸置信度判断，人脸识别 用户提交图片
	 * @author simony
	 * @param request
	 * @param file
	 * @param response
	 */
	@RequestMapping(value="/userfaceverify.m", method = RequestMethod.POST)
	public void userFaceVerify(HttpServletRequest request,
			@RequestParam(value="file",required=false) MultipartFile file,
			HttpServletResponse response,String publickey){
		HttpRequests httpRequests = faceAddAdd.getTool(); //face++ 工具
		CmsUser user = CmsUtils.getUser(request); // 获取用户
		FaceInfoM faceInfo = new FaceInfoM();
		//最小权限默认认证失败，认证成功后在set 认证成功。
		faceInfo.setStatus(FaceInfoM.ISNOTTHESAMEPERSON);
		CmsUserExt userExt= cmsUserExtMng.findById(user.getUserId());
		if (userExt.getUserFace() == null) { //如果用户还未创建人脸信息返回
			faceInfo.setStatus(FaceInfoM.ISNOTTHESAMEPERSON);
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return; 
		}
		String username = user.getUsername();
		byte[] img = null; //用于接收图片二进制值
		String faceId = null;
		JSONObject result = null;
		JSONObject detectout = null;
		String flag = null;
		if (file !=null) {
			try {
				img = file.getBytes();
			} catch (IOException e) {
				e.printStackTrace();
				return;
			}
		}
		else {
			return; //如果未上传图片则返回
		}
		
		try {       
			//人脸检测得到人脸信息 用于下一步验证
			detectout =  httpRequests.detectionDetect(new PostParameters().setImg(img));
		} catch (FaceppParseException e) {
			e.printStackTrace(); //人脸检测出错
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		
		try {
			faceId = detectout.getJSONArray("face").getJSONObject(0).getString("face_id");
		} catch (JSONException e1) {
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		} //由人脸检测得到的结果获取人脸id
		
	    if (faceId == null) {
			//如果上传图片无人脸返回
	    	ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		PostParameters parameter =  new PostParameters();
		parameter.setPersonName(username);
		parameter.setFaceId(faceId);
		try {
			result = httpRequests.recognitionVerify(parameter);
		} catch (FaceppParseException e) { //人脸验证过程出错
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		try {
			flag = result.get("is_same_person").toString();
		} catch (JSONException e) {
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		if (flag.equals("true")) {
			//认证为同一个人
			faceInfo.setStatus(FaceInfoM.ISTHESAMEPERSON);
			faceInfo.setPersonId(userExt.getUserFace());
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
		else {
			ClientUtils.resultResponse(response,faceInfo,publickey);
			return;
		}
	}
	
	private WebErrors validateSubmit(String username, String password,
			Integer errorRemaining, HttpServletRequest request,
			HttpServletResponse response) {
		WebErrors errors = WebErrors.create(request);
		if (errors.ifOutOfLength(username, "username", 1, 100)) {
			return errors;
		}
		if (errors.ifOutOfLength(password, "password", 1, 32)) {
			return errors;
		}
		return errors;
	}
	
	/**
	 * 删除错误记录Cookie
	 * @param request
	 * @param response
	 */
	private void removeCookieErrorRemaining(HttpServletRequest request,
			HttpServletResponse response) {
		CookieUtils.cancleCookie(request, response, COOKIE_ERROR_REMAINING,
				null);
	}

	@Autowired
	private UnifiedUserService unifiedUserMng;
	@Autowired
	private ImageCaptchaService imageCaptchaService;
	@Autowired
	private CmsUserService cmsUserMng;
	@Autowired
	private AuthenticationService authMng;
	@Autowired
	private SessionProvider session;
	@Autowired
	private ConfigService configMng;
	@Autowired
	private CmsUserExtService cmsUserExtMng;
	@Autowired
	private FaceAddAdd faceAddAdd;
}
